KeyedItem

Use this in the singular class which would describe a row in your database. ClusteredIndexAttribute is the unique constraint associated with the clustered index.

Members

Functions

checkConstraints
void checkConstraints()

Checks if any of the members of T have values that violate their check constraint.

markAsSaved
void markAsSaved()

Changes this to not contain changes. Should only be used after a save.

notify
void notify(string propertyName)

Notifies this which property changed. If the property is part of the clustered index then the clustered index is updated. This also emits a signal with the property name that changed along with the clustered index.

setClusteredIndex
void setClusteredIndex()

Sets the clustered index for this.

Mixins

emitChange
mixin Signal!(string, typeof(_key)) emitChange

The signal used to emit changes that occur in this.

Properties

containsChanges
bool containsChanges [@property getter]

Read-only property telling if this contains changes.

key
ClusteredIndex key [@property getter]

The clustered index property for the class.

Structs

ClusteredIndex
struct ClusteredIndex

Clustered index struct created at compile-time. This is used to compare classes. The members are the members of the class marked with the attribute selected as the Clustered Index.

Examples

1     class Candy
2     {
3     private:
4         string _name;
5         int _ranking;
6     public:
7         // name is the primary key
8         @PrimaryKeyColumn @NotNull
9         @property string name() const nothrow pure @safe @nogc
10         {
11             return _name;
12         }
13         @property void name(string value)
14         {
15             setter(_name, value);
16         }
17         // ranking must be unique among all the other records
18         @UniqueConstraintColumn!("uc_Candy_ranking")
19         @property int ranking() const nothrow pure @safe @nogc
20         {
21             return _ranking;
22         }
23         // making sure that ranking will always be above 0
24         @CheckConstraint!(a => a > 0, "chk_Candy_ranking")
25         @property void ranking(int value)
26         {
27             setter(_ranking, value);
28         }
29         this(string name, int ranking)
30         {
31             this._name = name;
32             this._ranking = ranking;
33             initializeKeyedItem();
34         }
35 
36         // The primary key is now the clustered index as it is by default
37         mixin KeyedItem!(PrimaryKeyColumn);
38     }
39 
40     // below is what is created when you include the mixin KeyedItem
41     // ClusteredIndex is alias'd as PrimaryKey since we said the
42     // primary key is our clustered index above.
43     // this also creates a uc_Candy_ranking struct and key since
44     // we labeled ranking with @UniqueConstraintColumn!("uc_Candy_ranking")
45     enum candyStructs =
46 `public:
47     final alias PrimaryKey = ClusteredIndex;
48     final alias PrimaryKey_key = key;
49     final struct uc_Candy_ranking
50     {
51         typeof(Candy._ranking) ranking;
52         mixin opAAKey!(uc_Candy_ranking);
53     }
54     final @property uc_Candy_ranking uc_Candy_ranking_key() const nothrow pure @safe @nogc
55     {
56         auto _uc_Candy_ranking_key = uc_Candy_ranking();
57         _uc_Candy_ranking_key.ranking = this._ranking;
58         return _uc_Candy_ranking_key;
59     }
60 `;
61     import db_constraints.utils.meta : createConstraintStructs;
62     static assert(createConstraintStructs!(Candy, "PrimaryKey") == candyStructs);
63     assert(createConstraintStructs!(Candy, "PrimaryKey") == candyStructs);
64 
65 
66     // source: http://www.bloomberg.com/ss/09/10/1021_americas_25_top_selling_candies/10.htm
67     auto i = new Candy("Opal Fruit", 17);
68 
69     // i does not contain changes
70     assert(!i.containsChanges);
71 
72     auto pk = Candy.PrimaryKey("Opal Fruit");
73     // the key property is the clustered index
74     // since we said the primary key is the clustered index
75     // i.key and pk are equal
76     assert(i.key == pk);
77     // PrimaryKey_key is an alias for key
78     assert(i.key == i.PrimaryKey_key);
79     // the primary key struct has member name since that was marked
80     // with @PrimaryKeyColumn
81     assert(i.key.name == pk.name);
82     assert(i.name == pk.name);
83 
84     auto j = new Candy("Opal Fruit", 16);
85     // since name is the primary key i and j are equal because
86     // the names are equal
87     // even though the ranking is different
88     assert(i.key == j.key);
89     assert(i.ranking != j.ranking);
90 
91     // in 1967 Opal Fruits came to America and changed its name
92     i.name = "Starburst";
93     // i now contains changes since we changed the name
94     assert(i.containsChanges);
95     i.markAsSaved();
96     // once we mark it as saved it no longer contains changes
97     assert(!i.containsChanges);
98 
99     // by changing the name it also changes the primary key
100     // so now i.key should not equal the pk we defined above
101     // or j.key
102     assert(i.key != pk);
103     assert(i.key != j.key);
104 
105     import std.exception : assertThrown;
106     import db_constraints.db_exceptions : CheckConstraintException;
107     // we expect setting the ranking to 0 will result in an exception
108     // since we labeled that column with
109     // @CheckConstraint!(a => a > 0, "chk_Candy_ranking")
110     assertThrown!CheckConstraintException(i.ranking = 0);

Meta